package com.niiwoo.civet.account.service.local.check.job.apiservice.withdraw;

import com.dangdang.ddframe.rdb.sharding.api.HintManager;
import com.dangdang.ddframe.rdb.sharding.hint.HintManagerHolder;
import com.github.pagehelper.PageHelper;
import com.niiwoo.civet.account.dao.entity.AccountBase;
import com.niiwoo.civet.account.dao.entity.AccountCheckingException;
import com.niiwoo.civet.account.dao.entity.AccountCheckingWithdraw;
import com.niiwoo.civet.account.dao.entity.BankCard;
import com.niiwoo.civet.account.dao.entity.WithdrawOrder;
import com.niiwoo.civet.account.dao.mapper.AccountBaseMapperExt;
import com.niiwoo.civet.account.dao.mapper.AccountCheckingWithdrawMapperExt;
import com.niiwoo.civet.account.dao.mapper.BankCardMapperExt;
import com.niiwoo.civet.account.dao.mapper.WithdrawOrderMapperExt;
import com.niiwoo.civet.account.dto.request.AccountCheckingWithdrawRequestDTO;
import com.niiwoo.civet.account.service.local.check.job.api.CheckDetailService;
import com.niiwoo.civet.account.service.local.check.job.api.ParseService;
import com.niiwoo.civet.account.service.local.check.job.enums.CheckResultEnum;
import com.niiwoo.civet.account.service.local.check.job.enums.HandleTypeEnum;
import com.niiwoo.civet.account.service.local.check.job.util.DateUtil;
import com.niiwoo.tripod.base.component.PrivacyMasks;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Slf4j
@Service
public class WithdrawCheckDetailServiceImpl implements CheckDetailService<AccountCheckingWithdraw>,ParseService<AccountCheckingWithdraw> {
    @Autowired
    private AccountCheckingWithdrawMapperExt accountCheckingWithdrawMapperExt;
    @Autowired
    private WithdrawOrderMapperExt withdrawOrderMapperExt;
    @Autowired
    private AccountBaseMapperExt accountBaseMapperExt;
    @Autowired
    private PrivacyMasks privacyMasks;
    @Autowired
    private BankCardMapperExt bankCardMapperExt;

    @Override
    public List<AccountCheckingWithdraw> load(Long checkRecordId, int page, int pageSize) {
    	// shardingjdbc 强制走主库
		if (!HintManagerHolder.isMasterRouteOnly()) {
            HintManagerHolder.clear();
            HintManager hintManager = HintManager.getInstance();
            hintManager.setMasterRouteOnly();
        }
		log.debug("is matster route only : {}", HintManagerHolder.isMasterRouteOnly());
        AccountCheckingWithdrawRequestDTO accountCheckingWithdrawRequestDTO = new AccountCheckingWithdrawRequestDTO();
        PageHelper.startPage(page, pageSize);
        accountCheckingWithdrawRequestDTO.setCheckingRecordId(checkRecordId);
        accountCheckingWithdrawRequestDTO.setStatus(Byte.valueOf("1"));
        List<AccountCheckingWithdraw> accountCheckingWithdrawsList = (List<AccountCheckingWithdraw>) accountCheckingWithdrawMapperExt.queryCheckingWithdrawPage(accountCheckingWithdrawRequestDTO);
        return accountCheckingWithdrawsList;
    }

    @Override
    public void batchUpdateCheckDetailStatus(Long checkRecordId, Byte status) {
        accountCheckingWithdrawMapperExt.updateByRecordIdSetStatus(checkRecordId,status);
    }

    @Override
    public AccountCheckingException check(AccountCheckingWithdraw accountCheckingWithdraw, String checkDate) {

        WithdrawOrder withdrawOrder = withdrawOrderMapperExt.queryWithdrawOrderByRequestNo(accountCheckingWithdraw.getPlatformRequestNo());
        AccountCheckingException accountCheckingException = new AccountCheckingException();
        accountCheckingWithdraw.setStatus(Byte.valueOf("2"));
        List<String> errors = new ArrayList<String>();
        //记录判断
        if( null == withdrawOrder ){
            accountCheckingException.setHandleType(HandleTypeEnum.BACK_ONLY.getIndex());
            errors.add(CheckResultEnum.NO_RECORD.getName());
            return submit(accountCheckingWithdraw,accountCheckingException,withdrawOrder,errors,checkDate);
        }

        //资金判断
        if( accountCheckingWithdraw.getAmount().compareTo(withdrawOrder.getAmount()) != 0){
            accountCheckingException.setHandleType(HandleTypeEnum.BOTH_ERROR.getIndex());
            errors.add(CheckResultEnum.AMOUNT_NOT_EQUAL.getName());
        }
        if( accountCheckingWithdraw.getArrivalAmount().compareTo(withdrawOrder.getRealAmout()) != 0 ){
            accountCheckingException.setHandleType(HandleTypeEnum.BOTH_ERROR.getIndex());
            errors.add(CheckResultEnum.REAL_AMOUNT_NOT_EQUAL.getName());
        }
        if( accountCheckingWithdraw.getPayrollAmount().compareTo(withdrawOrder.getAdvanceAmount()) !=0){
            accountCheckingException.setHandleType(HandleTypeEnum.BOTH_ERROR.getIndex());
            errors.add(CheckResultEnum.ADVANCE_AMOUNT_NOT_EQUAL.getName());
        }
        if( !accountCheckingWithdraw.getBankCode().equals(withdrawOrder.getBankCode())){
            accountCheckingException.setHandleType(HandleTypeEnum.NORMAL.getIndex());
            errors.add(CheckResultEnum.BANK_CORD_ERROR.getName());
        }
        BankCard bankCard = bankCardMapperExt.selectByPrimaryKey(withdrawOrder.getBankCardId());
        if( null == bankCard ){
            accountCheckingException.setHandleType(HandleTypeEnum.BOTH_ERROR.getIndex());
            errors.add(CheckResultEnum.BANK_CARD_IS_NULL.getName());
        }
        String bankCardNO = privacyMasks.decryptPrivacy(bankCard.getBankAccountNo());
        if( !bankCardNO.substring(bankCardNO.length() - 4 , bankCardNO.length()).equals(accountCheckingWithdraw.getBankAccountNo().substring(accountCheckingWithdraw.getBankAccountNo().length() - 4 , accountCheckingWithdraw.getBankAccountNo().length()))){
            accountCheckingException.setHandleType(HandleTypeEnum.NORMAL.getIndex());
            errors.add(CheckResultEnum.BANK_CORD_NO_ERROR.getName());
        }
        //平台用户编号验证
        {
            AccountBase accountBase = accountBaseMapperExt.selectByPrimaryKey(withdrawOrder.getAccountId());
            if( !accountCheckingWithdraw.getPlatformUserNo().equals(accountBase.getAccountNo())){
                errors.add(CheckResultEnum.PLATFORM_USER_NO_ERROR.getName());
                accountCheckingException.setHandleType(HandleTypeEnum.BOTH_ERROR.getIndex());
            }
        }
        //提现方式
        switch(withdrawOrder.getWithdrawType()){
            case 1: //普通提现
                if(!"NORMAL".equals(accountCheckingWithdraw.getWithdrawWay())){
                    errors.add(CheckResultEnum.WITHDRAW_WAY_ERROR.getName());
                    accountCheckingException.setHandleType(HandleTypeEnum.BOTH_ERROR.getIndex());
                }
                break;
            case 2:
                if(!"URGENT".equals(accountCheckingWithdraw.getWithdrawWay())){
                    errors.add(CheckResultEnum.WITHDRAW_WAY_ERROR.getName());
                    accountCheckingException.setHandleType(HandleTypeEnum.BOTH_ERROR.getIndex());
                }
                break;
            case 3:
                if(!"NORMAL_URGENT".equals(accountCheckingWithdraw.getWithdrawWay())){
                    errors.add(CheckResultEnum.WITHDRAW_WAY_ERROR.getName());
                    accountCheckingException.setHandleType(HandleTypeEnum.BOTH_ERROR.getIndex());
                }
                break;
            default:
                errors.add(CheckResultEnum.WITHDRAW_WAY_ERROR.getName());
                accountCheckingException.setHandleType(HandleTypeEnum.BOTH_ERROR.getIndex());
                break;
        }
        //状态判断
        if("SUCCESS".equals(accountCheckingWithdraw.getWithdrawStatus())){
            if( !withdrawOrder.getStatus().equals((byte)3)){
                accountCheckingException.setHandleType(HandleTypeEnum.BOTH_ERROR.getIndex());
                errors.add(CheckResultEnum.PROCCESS_STATUS.getName());
            }
        }else if("REMITING".equals(accountCheckingWithdraw.getWithdrawStatus())){
            if( !withdrawOrder.getStatus().equals((byte)2)) {
                accountCheckingException.setHandleType(HandleTypeEnum.BOTH_ERROR.getIndex());
                errors.add(CheckResultEnum.PROCCESS_STATUS.getName());
            }
        }else if("ACCEPT".equals(accountCheckingWithdraw.getWithdrawStatus())){
            Set<Byte> allowSet = new HashSet<Byte>();
            allowSet.add((byte)1);
            allowSet.add((byte)2);
            if( !allowSet.contains(withdrawOrder.getStatus()) && !allowSet.contains(withdrawOrder.getAuditStatus())) {
                accountCheckingException.setHandleType(HandleTypeEnum.BOTH_ERROR.getIndex());
                errors.add(CheckResultEnum.PROCCESS_STATUS.getName());
            }
        }else if("FAIL".equals(accountCheckingWithdraw.getWithdrawStatus())){
            if( !withdrawOrder.getStatus().equals((byte)4)){
                accountCheckingException.setHandleType(HandleTypeEnum.BOTH_ERROR.getIndex());
                errors.add(CheckResultEnum.PROCCESS_STATUS.getName());
            }
        }else{
            accountCheckingException.setHandleType(HandleTypeEnum.BOTH_ERROR.getIndex());
            errors.add(CheckResultEnum.PROCCESS_STATUS.getName());
        }
        return submit(accountCheckingWithdraw,accountCheckingException,withdrawOrder,errors,checkDate);
    }

    /**
     * 提交数据
     * @param accountCheckingWithdraw
     * @param accountCheckingException
     * @param withdrawOrder
     * @param errors
     */
    private AccountCheckingException submit(AccountCheckingWithdraw accountCheckingWithdraw, AccountCheckingException accountCheckingException, WithdrawOrder withdrawOrder, List<String> errors, String checkDate){
        if( null != errors && errors.size() != 0 ){
            accountCheckingException.setStatus(Byte.valueOf("1"));
            accountCheckingException.setBusinessType(Byte.valueOf("01"));
            accountCheckingException.setOrderNo(accountCheckingWithdraw.getOrderNo());
            accountCheckingException.setCheckingType(Byte.valueOf("3"));
            accountCheckingException.setCheckingRecordId(accountCheckingWithdraw.getCheckingRecordId());
            accountCheckingException.setCheckingDetailId(accountCheckingWithdraw.getId());
            accountCheckingException.setPlatformRecordId((null == withdrawOrder) ? null : withdrawOrder.getId());
            accountCheckingException.setCreateTime(new Date());
            accountCheckingException.setBillDate(checkDate);
            accountCheckingException.setDescription(errors.toString());
            accountCheckingWithdraw.setRemark(errors.toString());

            return accountCheckingException;
        }
        return null ;
    }

    @Override
    public AccountCheckingWithdraw parse(Long recordId, String content) {
        if (content == null || "".equals(content))
            return null;

        String[] sArr = content.split(",");

        AccountCheckingWithdraw record = new AccountCheckingWithdraw();
        //0提现时间,1平台商编,2平台请求流水号,3订单号,4业务类型,5金额,6币种,7会员编号,8平台用户编号,
        //9银行卡号,10银行编码,11到账金额,12备注,13提现状态,14提现方式,15垫资金额,16出款类型,17提现类型
        record.setWithdrawTime(DateUtil.parseT(sArr[0]));
        record.setPlatformMerchantNo(sArr[1]);
        record.setPlatformRequestNo(sArr[2]);
        record.setOrderNo(sArr[3]);
        record.setBusinessType(Byte.valueOf(sArr[4]));
        record.setAmount(BigDecimal.valueOf(Double.valueOf(sArr[5])));
        record.setAmonnt("人民币"); //6-人民币
        record.setMemberNo(sArr[7]);
        record.setPlatformUserNo(sArr[8]);
        record.setBankAccountNo(sArr[9]);
        record.setBankCode(sArr[10]);
        record.setArrivalAmount(BigDecimal.valueOf(Double.valueOf(sArr[11])));
        record.setRemark(sArr[12]);
        record.setWithdrawStatus(sArr[13]);
        record.setWithdrawWay(sArr[14]);
        record.setPayrollAmount(BigDecimal.valueOf(Double.valueOf(sArr[15])));
        record.setRemitType(sArr[16]);
        record.setWithdrawForm(sArr[17]);

        record.setStatus((byte) 1); // 1待处理
        record.setCheckingRecordId(recordId);
        return record;
    }

    @Override
    public void save(List<AccountCheckingWithdraw> list) {
        if (list == null || list.isEmpty())
            return;
        //accountCheckingWithdrawMapperExt.insertBatch(list);
        for(AccountCheckingWithdraw accountCheckingWithdraw : list){
            accountCheckingWithdrawMapperExt.insert(accountCheckingWithdraw);
        }
    }

    @Override
    public void deleteCheckRecord(Long recordId) {
        accountCheckingWithdrawMapperExt.deleteCheckRecord(recordId);
    } 
    
    @Override
    public void extendBusiness(Long checkRecordId) {
    	//暂无业务
    }

	@Override
	public void deleteAllCheckSuccessBankOrder(Long checkRecordId) {
        accountCheckingWithdrawMapperExt.deleteCheckRecord(checkRecordId);
	}
}
